package com.gonsin.gmessage.logic.render;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.gonsin.gmessage.logic.render.args.ArgsParamDescription;
import lombok.Data;

import java.util.*;

/**
 * 发送器的描述
 */
@Data
public class SenderDescription {

    /**
     * 接口描述
     */
    private String note;

    /**
     * mqtt监听的topic
     */
    private String topicUrl;

    /**
     * mqtt监听的topic
     */
    private String topicUrlDot;


    /**
     * 其他说明
     */
    private String summary;

    /**
     * 第一指令
     */
    private String firstCmd;

    /**
     * 第二指令
     */
    private String subCmd;

    /**
     * 发送的json内容
     */
    private String json;

    /**
     * 参数列表
     */
    private String parameterList;

    /**
     * mqtt 发送质量
     */
    private int qos = 0;

    /**
     * MQTT v5新增特性，共享topic
     */
    private boolean share = false;

    /**
     * 该接口的参数
     */
    private List<ArgsParamDescription> parameters;

    public void createParameterList(){
        StringBuffer sb = new StringBuffer();
        for(ArgsParamDescription arg : parameters){
            appendParameter(0, sb, arg);
        }
        this.parameterList = sb.toString();
    }


    public void appendParameter(int level, StringBuffer sb, ArgsParamDescription arg){
        if(arg.getChild() == null){
            sb.append("|");
            if(level > 0){
                for(int i = 0; i < level * 2; i++){
                    sb.append("&nbsp;");
                }
                sb.append("┗");
                sb.append("&nbsp;");
            }
            sb.append(arg.getKeyName());
            sb.append("|");
            sb.append(arg.getNote());
            sb.append("|");
            sb.append(arg.isRequired() ? "是" : "否");
            sb.append("|");
            sb.append(arg.getType());
            sb.append("|");
            sb.append(arg.getDemo());
            sb.append("|");
            sb.append("\n");
            return;
        }
        sb.append("|");
        // 参数名字
        if(level > 0){
            for(int i = 0; i < level * 2; i++){
                sb.append("&nbsp;");
            }
            sb.append("┗");
            sb.append("&nbsp;");
        }
        sb.append(arg.getKeyName());
        sb.append("|");
        sb.append(arg.getNote());
        sb.append("|");
        sb.append(arg.isRequired() ? "是" : "否");
        sb.append("|");
        sb.append(arg.getType());
        sb.append("|");
        sb.append("|");
        sb.append("\n");
        for(ArgsParamDescription c : arg.getChild()){
            appendParameter(level + 1, sb, c);
        }
    }


    /**
     * 创建json内容
     */
    public void createJson() {
        Map<String, Object> root = new HashMap<>();
        root.put("head", "gonsin");

        Map<String, Object> cmd = new HashMap<>();
        root.put("cmd", cmd);
        cmd.put("firstcmd", this.firstCmd);
        cmd.put("subcmd", this.subCmd);
        cmd.put("response", 0);

        Map<String, Object> args = new HashMap<>();
        root.put("args", args);
        for(ArgsParamDescription a : parameters){
            if(a.getChild() == null && !a.isBasicClassArray()){
                args.put(a.getKeyName(), a.getDemo() == null ? "" : a.getDemo());
                continue;
            }

            if("Array".equalsIgnoreCase(a.getType())){
                List<Object> aList = new ArrayList<>();
                args.put(a.getKeyName(), aList);
                if(!a.isBasicClassArray()){
                    Map<String, Object> aMap = new HashMap<>();
                    aList.add(aMap);
                    for(ArgsParamDescription c : a.getChild()){
                        putObject(aMap, c);
                    }
                } else {
                    if("String".equals(a.getInnerClass())){
                        aList.add(Objects.toString(a.getDemo()));
                    } else {
                        Object item = null;
                        if(a.getDemo() != null){
                            try {
                                item = Integer.valueOf(Objects.toString(a.getDemo()));
                            } catch (Exception ex) {

                            }
                        }
                        if(item == null){
                            item = 0;
                        }
                        aList.add(item);
                    }
                }
            } else {
                Map<String, Object> aMap = new HashMap<>();
                args.put(a.getKeyName(), aMap);
                for(ArgsParamDescription c : a.getChild()){
                    putObject(aMap, c);
                }
            }

        }


        this.json = JSON.toJSONString(
                root,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
    }

    private void putObject(Map<String, Object> aMap, ArgsParamDescription a){
        if(a.getChild() == null){
            aMap.put(a.getKeyName(), a.getDemo() == null ? "" : a.getDemo());
            return;
        }

        Map<String, Object> subMap = new HashMap<>();
        aMap.put(a.getKeyName(), subMap);
        for(ArgsParamDescription c : a.getChild()){
            putObject(subMap, c);
        }
    }
}
